package com.nit.bike.service.bike.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.nit.bike.dto.bike.CardDTO;
import com.nit.bike.dto.bike.CardRecordDTO;
import com.nit.bike.dto.utils.OpResultDTO;
import com.nit.bike.dto.utils.PagingDTO;
import com.nit.bike.dto.utils.TableReqDTO;
import com.nit.bike.dto.utils.TableRspDTO;
import com.nit.bike.entity.bike.CardEntity;
import com.nit.bike.entity.bike.CardRecordEntity;
import com.nit.bike.mapper.bike.CardRecordMapper;
import com.nit.bike.service.bike.CardRecordService;
import com.nit.bike.service.bike.CardService;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class CardRecordServiceImpl implements CardRecordService {
    @Resource
    private CardService cardService;
    @Resource
    private CardRecordMapper cardRecordMapper;

    @Override
    public TableRspDTO list4Table(TableReqDTO req, Long userId) throws Exception {
        CardDTO cardDTO = cardService.query(userId);
        if (cardDTO == null || cardDTO.getCardId() == null) {
            PagingDTO pagingDTO = new PagingDTO(
                    req.getPageNo(),
                    req.getPageSize(),
                    0L,
                    new ArrayList<>()
            );
            return new TableRspDTO(pagingDTO);
        }
        String begDate = req.parseQueryParam("begDate");
        String endDate = req.parseQueryParam("endDate");
        if (begDate == null || endDate == null) {
            begDate = null;
            endDate = null;
        }
        PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<CardRecordDTO> DTOs = cardRecordMapper.list4Table(
                userId,
                req.parseQueryParam("recordType"),
                req.parseQueryParam("stationId"),
                req.parseQueryParam("bikeId"),
                begDate,
                endDate,
                req.getSortField(),
                req.getSortOrder()
        );
        return new TableRspDTO(new PagingDTO(
                req.getPageNo(),
                req.getPageSize(),
                new PageInfo<>(DTOs).getTotal(),
                DTOs));
    }

    @Override
    public TableRspDTO list4Bike(TableReqDTO req) throws Exception {
        String begDate = req.parseQueryParam("begDate");
        String endDate = req.parseQueryParam("endDate");
        if (begDate == null || endDate == null) {
            begDate = null;
            endDate = null;
        }
        PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<CardRecordDTO> DTOs = cardRecordMapper.list4Bike(
                req.parseQueryParam("stationId"),
                req.parseQueryParam("bikeId"),
                begDate,
                endDate,
                req.getSortField(),
                req.getSortOrder()
        );
        return new TableRspDTO(new PagingDTO(
                req.getPageNo(),
                req.getPageSize(),
                new PageInfo<>(DTOs).getTotal(),
                DTOs));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer add(CardRecordDTO cardRecordDTO) throws Exception {
        MapperFactory factory = new DefaultMapperFactory.Builder().build();
        CardRecordEntity entity = factory.getMapperFacade().map(cardRecordDTO, CardRecordEntity.class);
        entity.setGmtCreate(new Date());

        CardEntity cardEntity = new CardEntity();
        cardEntity.setCardId(entity.getCardId());
        cardEntity.setBalance(entity.getRecordType() == 1 ? entity.getMoney() : entity.getMoney().negate());
        cardEntity.setDistance(entity.getDistance());
        cardEntity.setDuring(entity.getDuring());
        cardService.updateData(cardEntity);
        return cardRecordMapper.insertSelective(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO pay(CardRecordDTO cardRecordDTO) throws Exception {
        return new OpResultDTO();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer update(CardRecordDTO cardRecordDTO) throws Exception {
        MapperFactory factory = new DefaultMapperFactory.Builder().build();
        CardRecordEntity entity = factory.getMapperFacade().map(cardRecordDTO, CardRecordEntity.class);
        return cardRecordMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer remove(String ids) throws Exception {
        String[] idArr = ids.split(",");
        for (String s : idArr) {
            cardRecordMapper.deleteByPrimaryKey(Long.parseLong(s));
        }
        return idArr.length;
    }
}
